using System;
using System.Linq.Expressions;
using Karma.Framework.Core.Domain.Tools.Import.Data;
using Karma.Framework.Core.Domain.Tools.Import.Validation;

namespace Karma.Framework.Core.Domain.Tools.Import.Configuration.Fluent
{
    public class FluentTransientConfiguration<T>
    {
        protected EntityConfiguration _configuration;

        public FluentTransientConfiguration()
        {
            _configuration = new EntityConfiguration(typeof(T));
        }

        public FluentTransientConfiguration<T> With
        {
            get
            {
                return this;
            }
        }

        public EntityConfiguration Configuration
        {
            get
            {
                return _configuration;
            }
        }

        public FluentPropertyConfiguration<T, TProperty> Property<TProperty>(Expression<Func<T, TProperty>> expression)
            where TProperty : DomainObject
        {
            var property = new FluentPropertyConfiguration<T, TProperty>(this, expression);
            _configuration.AddProperty(property.Configuration);
            return property;
        }

        public FluentValuePropertyConfiguration<T, TProperty> ValueProperty<TProperty>(Expression<Func<T, TProperty>> expression)
            where TProperty : struct
        {
            var property = new FluentValuePropertyConfiguration<T, TProperty>(this, expression);
            _configuration.AddProperty(property.Configuration);
            return property;
        }

        public FluentTransientConfiguration<T> Alias(string name)
        {
            _configuration.Alias = name;
            return this;
        }

        public FluentTransientConfiguration<T> Persister<TPersister>() where TPersister : IEntityPersister
        {
            _configuration.Perister = typeof(TPersister);
            return this;
        }

        public FluentTransientConfiguration<T> Listener<TListener>()
        {
            _configuration.AddListener(typeof(TListener));
            return this;
        }

        public FluentTransientConfiguration<T> ReferenceValidator<TValidator>() where TValidator : IReferenceValidator
        {
            _configuration.Validator = typeof(TValidator);
            _configuration.ReplaceDefaultValidator = true;
            return this;
        }

        public FluentTransientConfiguration<T> ReferenceValidator<TValidator>(bool replaceDefaultValidator) where TValidator : IReferenceValidator
        {
            _configuration.Validator = typeof(TValidator);
            _configuration.ReplaceDefaultValidator = replaceDefaultValidator;
            return this;
        }
    }

    public class FluentEntityConfiguration<T> : FluentTransientConfiguration<T> where T : DomainObject
    {
        public FluentEntityConfiguration() : base()
        {
        }
    }
}